﻿using ImperialServer.Data.DAO;
using ImperialServer.Data.Interfaces;
using ImperialServer.Common.Entities;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using ImperialWebSite.Content.Resources;
using ImperialUtilities.Utilities;
using ImperialUtilities.Exceptions;
using ImperialWebSite.ImperialWS;

namespace ImperialWebSite.Controllers
{
    public class CitizenController: BaseController
    {
        private ImperialWebServiceSoapClient _webService;
        private IRegistryAccess _daoRegistryAccess;
        private EventViewer _logger;

        public CitizenController()
        {
            _logger = new EventViewer("ImperialWebSite.Controllers");
            _daoRegistryAccess = new RegistryAccess(ConfigurationManager.ConnectionStrings["ImperialConnection"].ConnectionString);
            _webService = new ImperialWebServiceSoapClient();
        }

        /// <summary>
        /// Metodo que crea un objeto de tipo CitizenEntity
        /// </summary>
        /// <param name="usernameText">nombre de usuario</param>
        /// <param name="realnameText">nombre real</param>
        /// <param name="roleValue">id del rol</param>
        /// <param name="specieValue">id de la especie</param>
        /// <param name="statusValue">id del estatus</param>
        /// <returns>objeto lleno</returns>
        public CitizenEntity CreateNewCitizen(string usernameText, string realnameText, string roleValue, string roleName, string specieValue, string specieName, string statusValue, string statusName)
        {
            CitizenEntity newCitizen = null;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "CreateNewCitizen"));

                newCitizen = new CitizenEntity
                    {
                        Username = usernameText,
                        Realname = realnameText,
                        Role = new RoleEntity { Id = int.Parse(roleValue), RoleName = roleName },
                        Specie = new SpecieEntity { Id = int.Parse(specieValue), SpecieName = specieName },
                        UserStatus = new List<UserStatus>()
                    };
                newCitizen.UserStatus.Add(new UserStatus { Status = new StatusEntity { Id = int.Parse(statusValue), StatusName = statusName } });

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("CreateNewCitizen", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "CreateNewCitizen"));
            }
            return newCitizen;
        }

        /// <summary>
        /// Metodo que se encarga de realizar la llamada al servidor para insertar un nuevo ciudadano
        /// </summary>
        /// <param name="newStatus">objeto con los datos a insertar</param>
        /// <returns>true si fue exitosa, false si no</returns>
        public bool InsertNewCitizen(CitizenEntity newCitizen)
        {
            bool isSuccess = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "InsertNewCitizen"));

                isSuccess = _daoRegistryAccess.InsertNewCitizen(newCitizen);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("InsertNewCitizen", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "InsertNewCitizen"));
            }
            return isSuccess;
        }

        /// <summary>
        /// Metodo que indica si un roleName ya se encuentra registrado
        /// </summary>
        /// <param name="roleName">nombre de usuario</param>
        /// <param name="currentRoles">lista de ciudadanos ya registrados</param>
        /// <returns>true si existe, false si no</returns>
        public bool CitizenAlreadyRegistered(string username, object currentCitizens)
        {
            bool found = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "CitizenAlreadyRegistered"));

                DataTable dtCurrentCitizens = (DataTable)currentCitizens;
                DataRow[] drCurrentCitizen = dtCurrentCitizens.Select("username = '" + username.ToLower() + "'");
                found = drCurrentCitizen != null && drCurrentCitizen.Length > 0;

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("CitizenAlreadyRegistered", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "CitizenAlreadyRegistered"));
            }
            return found;
        }

        /// <summary>
        /// Metodo que se encarga de hacer la llamada al servidor para actualizar la informacion de un ciudadano
        /// </summary>
        /// <param name="roleName">objeto con los datos a actualizar</param>
        /// <returns>true si es exitosa, false si no</returns>
        public bool UpdateCitizen(CitizenEntity citizen)
        {
            bool isSuccess = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "UpdateCitizen"));

                isSuccess = _daoRegistryAccess.UpdateCitizen(citizen);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("UpdateCitizen", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "UpdateCitizen"));
            }
            return isSuccess;
        }

        /// <summary>
        /// Metodo que se encarga de consultar un registro para saber si es igual a un parametro
        /// </summary>
        /// <param name="roleName">nombre de usuario</param>
        /// <param name="currentRoles">coleccion de registros</param>
        /// <param name="currentRole">registro a consultar</param>
        /// <returns>true si es el mismo registro, false si no</returns>
        public bool IsTheSameCitizen(string username, object currentCitizens, object currentCitizen)
        {
            bool isSameUser = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "IsTheSameCitizen"));

                DataTable dtCurrentCitizens = (DataTable)currentCitizens;
                DataRow[] drCurrentCitizen = dtCurrentCitizens.Select("idUser = " + currentCitizen.ToString());
                if (drCurrentCitizen != null && drCurrentCitizen.Length > 0)
                    isSameUser = drCurrentCitizen[0]["username"].ToString() == username;
                else
                {
                    _logger.WriteEventViewerLog("IsTheSameCitizen", Messages.failureTransactionMessage, true);
                    throw new ImperialException(Messages.failureTransactionMessage);
                }

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (ImperialException ie)
            {
                throw ie;
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("IsTheSameCitizen", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "IsTheSameCitizen"));
            }
            return isSameUser;
        }

        /// <summary>
        /// Metodo que se encarga de verificar si el nombre contiene la palabra skywalker
        /// </summary>
        /// <param name="RealNameText"></param>
        /// <returns></returns>
        public bool UserHasSkywalker(string RealNameText)
        {
            bool contained = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "UserHasSkywalker"));

                contained = RealNameText.ToLower().Trim().Contains(ConfigurationManager.AppSettings["forbiddenWord"]);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);
            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("UserHasSkywalker", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "UserHasSkywalker"));
            }
            return contained;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="newCitizen"></param>
        /// <returns></returns>
        public bool SendDataToWebService(CitizenEntity newCitizen)
        {
            var result = false;
            try
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.enterMessageInfo, "SendDataToWebService"));
                
                result = _webService.RegisterJediFile(newCitizen.Username, newCitizen.Realname, newCitizen.Role.RoleName, newCitizen.Specie.SpecieName, newCitizen.UserStatus[0].Status.StatusName);

                HttpContext.Current.Trace.Write(Messages.successfulTransactionMessage);

            }
            catch (Exception e)
            {
                _logger.WriteEventViewerLog("SendDataToWebService", e.Message, true);
                throw new ImperialException(Messages.failureTransactionMessage, e);
            }
            finally
            {
                HttpContext.Current.Trace.Write(string.Format(Messages.exitMessageInfo, "SendDataToWebService"));
            }
            return result;
        }

    }
}